#pragma once
#include <stdio.h>
#include <unordered_map>

class CsvParser 
{
private:
	typedef std::unordered_map<size_t, int> ID_TABLE;
	int m_row_count;
	int m_column_count;
	int m_column_name_idx;

	char* m_buffer;
	char* m_buffer_end;
	const char ** m_table_cells;

	ID_TABLE m_row_id_table;
	ID_TABLE m_col_id_table;

public:
    int GetWidth()      { return m_column_count; }
    int GetHeight()     { return m_row_count;    }
    int FindRow(const char* row_name);
    int FindColumn(const char* column_name);
    int GetString(int row_idx, int column_idx, const char* default_str, char* ret_str, unsigned int buf_max_size);
    int GetString(const char* row_name, const char* column_name, const char* default_str, char* ret_str, unsigned int buf_max_size);
    int GetString(int row_idx, const char* column_name, const char* default_str, char* ret_str, unsigned int buf_max_size);
    int GetInteger(int row_idx, int column_idx, int default_num, int* ret_num);
    int GetInteger(const char* row_name, const char* column_name, int default_num, int* ret_num);
    int GetInteger(int row_idx, const char* column_name, int default_num, int* ret_num);
    int GetFloat(int row_idx, int column_idx, float defalut_num, float* ret_num);
    int GetFloat(const char* row_name, const char* column_name, float default_num, float* ret_num);
    int GetFloat(int row_idx, const char* column_name, float default_num, float* ret_num);

public:
    CsvParser();
	CsvParser(int colname_idx);
    ~CsvParser();

    int  LoadFromFile(const char* path);
    int  LoadFromBuffer(const char* buffer, size_t size);

private:
    int  CreateTableCells();
    int  DestroyTableCells();
    int  CreateTableIndex();
    int  DestroyTableIndex();
    const char* GetCell(int row_idx, int column_idx);
    inline const char * FastGetCell(int row_idx, int column_idx);
    int  GetMaxRowCountAndMaxColumnCount(int& ret_row_count, int& ret_column_count);
};